package com.project.common.tools;


import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.project.common.config.OssConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.codec.multipart.FilePart;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.Objects;

/**
 * 功能描述
 *
 */
@Slf4j
public class OSSUtils {

    /**
     * 默认大小 50M
     */
    public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024;

    /**
     * 默认的文件名最大长度 100
     */
    public static final int DEFAULT_FILE_NAME_LENGTH = 100;

    public static final String upload2Oss(MultipartFile file, String[] allowedExtension, OssConfig ossConfig, String fileName) throws IOException {
        // 判断文件名长度
        int fileNamelength = Objects.requireNonNull(file.getOriginalFilename()).length();
        if (fileNamelength > OSSUtils.DEFAULT_FILE_NAME_LENGTH) {
            return "文件名不能超过100";
        }
        // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1（杭州）为例，Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
        String endpoint = ossConfig.getEndpoint();
        // 阿里云账号AccessKey拥有所有API的访问权限，风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维，请登录RAM控制台创建RAM用户。
        String accessKeyId = ossConfig.getSecretId();
        String accessKeySecret = ossConfig.getSecretKey();
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint,
                accessKeyId,
                accessKeySecret);
        if (StringUtils.isBlank(fileName)) {
            fileName = extractFilename(file);
        }
        if (fileName.startsWith("/")) {
            fileName = fileName.replaceFirst("/", "");
        }
        // 填写本地文件的完整路径。如果未指定本地路径，则默认从示例程序所属项目对应本地路径中上传文件流。
        InputStream inputStream = file.getInputStream();
        // 填写Bucket名称和Object完整路径。   Object完整路径中不能包含Bucket名称。
        ossClient.putObject(ossConfig.getBucketName(), fileName, inputStream);
        // 关闭OSSClient。
        ossClient.shutdown();
        return fileName;
    }

    /**
     * String myObjectName = "pioneer_mall/goods/" + fileName;
     *
     * @param ossConfig
     * @param fileName
     * @return
     */
    public static final String upload(InputStream inputStream, OssConfig ossConfig, String fileName) {
        // 判断文件名长度
        int fileNamelength = Objects.requireNonNull(fileName).length();
        if (fileNamelength > OSSUtils.DEFAULT_FILE_NAME_LENGTH) {
            return "文件名不能超过100";
        }
        OSS ossClient = new OSSClientBuilder().build(ossConfig.getEndpoint(), ossConfig.getSecretId(), ossConfig.getSecretKey());
        if (fileName.startsWith("/")) {
            fileName = fileName.replaceFirst("/", "");
        }
        ossClient.putObject(ossConfig.getBucketName(), fileName, inputStream);
        ossClient.shutdown();
        return fileName;
    }

    public static final String upload2OssUserStream(InputStream inputStream, OssConfig ossConfig, String fileName) {
        // 判断文件名长度
        int fileNamelength = Objects.requireNonNull(fileName).length();
        if (fileNamelength > OSSUtils.DEFAULT_FILE_NAME_LENGTH) {
            return "文件名不能超过100";
        }
        OSS ossClient = new OSSClientBuilder().build(ossConfig.getEndpoint(), ossConfig.getSecretId(), ossConfig.getSecretKey());
        if (fileName.startsWith("/")) {
            fileName = fileName.replaceFirst("/", "");
        }
        ossClient.putObject(ossConfig.getBucketName(), fileName, inputStream);
        ossClient.shutdown();
        return fileName;
    }

    /**
     * 编码文件名
     */
    public static final String extractFilename(MultipartFile file) {
        String fileName = null;
        String extension = getExtension(file);
        fileName = DateUtil.formatDate(new Date()) + "/" + IdUtil.getSnowflake().nextId() + "." + extension;
        return fileName;
    }

    /**
     * 获取文件名的后缀
     *
     * @param file 表单文件
     * @return 后缀名
     */
    public static final String getExtension(MultipartFile file) {
        String extension = FilenameUtils.getExtension(file.getOriginalFilename());
        if (StringUtils.isEmpty(extension)) {
            extension = MimeTypeUtils.getExtension(file.getContentType());
        }
        return extension;
    }

    public static final String getExtension(FilePart file) {
        String extension = FilenameUtils.getExtension(file.filename());
        if (StringUtils.isEmpty(extension)) {
            extension = MimeTypeUtils.getExtension(file.name());
        }
        return extension;
    }
}
